package com.cskaoyan.javase.oop3._1interface._0introduction;

/**
 * @description: 接口的引入
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * > 引例
 * > 回想Animal继承体系的案例，现在我们把Animal设计成抽象类
 * > 产品经理给了新需求
 * - 现在有一部分猫和狗，经过了特殊训练
 *   - 都可以直立行走（Walk Upright）和骑自行车（Ride Bike）
 * - 那么该怎么去描述这群特殊的猫狗呢？
 *
 * 主要问题是walkUpright和rideBike两个方法放在哪里的问题
 * 我们可以重新定义一个类,SuperCat和SuperDog,让它们继承Cat和Dog然后再新增两个方法
 * 这样设计是有改进的余地的:
 *      1,两个类中有相同的方法,可以复用,减少冗余
 *      2,直接定义两个额外方法的方式,无法体现额外训练,如果新增一个动物也能直立行走,无法体现这种训练的过程
 * 可以考虑抽取出两个方法作为两个抽象方法,放入一个抽象类中,然后让动物们继承,体现一个训练的过程
 *
 * 这样的想法是很好的,可实际上是做不到的,因为Java不支持多继承,一个类只能直接继承一个类,不能继承多个类
 *
 * 这个时候就需要一种新的数据类型, 这种新的数据类型不受java多继承限制,这就是接口interface
 * 接口: 接口interface是一种全新的,不同于类的数据类型,它也是引用数据类型,是和class同级别关系的引用数据类型
 * 定义语法:
 *      [访问权限修饰符] interface 接口名{
 *          //接口体
 *      }
 * 说明:
 *      1,访问权限修饰符这里和class完全一致,只有两个
 *      2,接口名也遵循大驼峰式的书写,在某些程序员群体中,喜欢在接口名前加一个大写的"I",比如ITest
 *          也有些程序员喜欢在接口的子类命名中,加后缀"Impl"
 *      3,接口的"继承",接口的子类,用的不是extends,而是implements(实现)
 *      4,接口虽然不是类,但是使用起来和类是一致的,所以程序员也经常说接口是"父类",接口有"子类"
 *      5,接口中是允许定义抽象方法的
 *      6,接口不受多继承限制,一个类可以在继承一个类的基础上再实现多个接口
 *      7,接口不能实例化
 *
 * 为什么使用接口?接口的优点:
 *      我们都知道继承中两个类是"is-a"的关系,子类是可以看成父类的
 *      但是在很多时候,我们需要继承,但是继承中的两个类没有"is-a"关系,这个时候从设计角度来说,不能使用继承
 *
 *      所以这个时候就需要一种新的两个类之间的关系,一种新的数据类型,来完成这个需求
 *      新的关系是"like-a",像xxx
 *      这种like-a的关系,更注重对功能(方法/行为)的扩展,而不注重两个对象之间有没有"is-a"关系
 *      java的接口可以和生活中的接口关联一下
 *
 */
public class Demo {
    public static void main(String[] args) {
        //'IA' is abstract; cannot be instantiated
        //IA i = new IA();

        ISkills is;
        is = new SuperDog();
        is = new SuperCat();
        is.walkUpright();
        is.rideBike();
        //is.shout();
        Animal a = new SuperCat();
        a.shout();

        IA ia = new SuperDog();
        //ia.wal
    }
}

abstract class Animal {
    public abstract void shout();
}

class Cat extends Animal {
    @Override
    public void shout() {
        System.out.println("猫叫");
    }
}

class Dog extends Animal {
    @Override
    public void shout() {
        System.out.println("狗叫");
    }
}

class SuperCat extends Cat implements ISkills {
    //直立行走和骑自行车的方法
    @Override
    public void walkUpright() {
        System.out.println("走路");
    }

    @Override
    public void rideBike() {
        System.out.println("骑自行车");
    }
}

class SuperDog extends Dog implements ISkills,IA{
    @Override
    public void walkUpright() {
        System.out.println("走路");
    }

    @Override
    public void rideBike() {
        System.out.println("骑自行车");
    }
}

abstract class AbstractSkills {
    public abstract void walkUpright();

    public abstract void rideBike();
}

//定义了一个接口
interface ISkills {
    public abstract void walkUpright();

    public abstract void rideBike();
}
interface IA{}